package xyz.ddlnt.serviceusr.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import xyz.ddlnt.commonutil.constant.FieldConstants;
import xyz.ddlnt.commonutil.enumeration.ResultCode;
import xyz.ddlnt.commonutil.exception.GlobalException;
import xyz.ddlnt.commonutil.util.RandomUtil;
import xyz.ddlnt.model.dto.NoteAddDTO;
import xyz.ddlnt.model.dto.NoteDTO;
import xyz.ddlnt.model.dto.NoteDirDTO;
import xyz.ddlnt.model.dto.PostDescriptionDTO;
import xyz.ddlnt.model.entity.Note;
import xyz.ddlnt.model.vo.NoteContentVO;
import xyz.ddlnt.model.vo.NoteVO;
import xyz.ddlnt.serviceusr.mapper.NoteMapper;
import xyz.ddlnt.serviceusr.service.NoteService;
import xyz.ddlnt.serviceusr.service.PostService;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author ZZULI_SE 210910
 * @data 2025/5/6 21:52
 */
@Slf4j
@Service
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements NoteService {

    @Resource
    private NoteMapper noteMapper;

    @Override
    public NoteVO addNote(NoteAddDTO noteAddDTO) {
        String title = FieldConstants.NOTE_TITLE;
        if (noteAddDTO.getNoteTitle() != null && !noteAddDTO.getNoteTitle().isEmpty()) {
            title = noteAddDTO.getNoteTitle();
        }
        Long id = RandomUtil.generate12DigitRandomNumber();
        LocalDateTime now = LocalDateTime.now();
        Note note = Note.builder()
                .id(id)
                .userId(noteAddDTO.getUserId())
                .noteTitle(title)
                .noteDirectory(new JSONArray().toJSONString())
                .type(noteAddDTO.getType())
                .layer(noteAddDTO.getLayer())
                .dirPrevNodeId(noteAddDTO.getDirPrevNodeId())
                .dirChildNodes(new JSONArray().toJSONString())
                .childNodes(new JSONArray().toJSONString())
                .createTime(now)
                .updateTime(now)
                .build();
        try {
            noteMapper.insert(note);
        }catch (Exception e) {
            log.error("异常处理: {}", e.getMessage(), e);
            log.error("原因: ", e.getCause());
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return NoteVO.builder()
                .id(id)
                .createTime(now)
                .build();
    }

    @Override
    public Boolean updateNoteTitle(NoteDTO noteDTO) {
        LambdaUpdateWrapper<Note> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Note::getNoteTitle, noteDTO.getNoteTitle())
                .eq(Note::getId, noteDTO.getId());
        try {
            noteMapper.update(updateWrapper);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return true;
    }

    @Override
    public Boolean updateNote(NoteDTO noteDTO) {
        // 判断目录是否为空，若不为空，则转换为JSON字符串
        boolean isEmpty = false;
        String jsonString = "";
        if (noteDTO.getNoteDirectory() != null && !noteDTO.getNoteDirectory().isEmpty()) {
            isEmpty = true;
            jsonString = noteDTO.getNoteDirectory().toJSONString();
        }
        // 更新笔记·
        LambdaUpdateWrapper<Note> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .set(!StringUtils.isEmpty(noteDTO.getNoteTitle()), Note::getNoteTitle, noteDTO.getNoteTitle())
                .set(!StringUtils.isEmpty(noteDTO.getSummary()), Note::getSummary, noteDTO.getSummary())
                .set(isEmpty, Note::getNoteDirectory, jsonString)
                .set(!StringUtils.isEmpty(noteDTO.getNoteContent()), Note::getNoteContent, noteDTO.getNoteContent())
                .set(Note::getUpdateTime, LocalDateTime.now())
                .eq(Note::getId, noteDTO.getId());
        try {
            noteMapper.update(updateWrapper);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return true;
    }

    @Override
    public List<NoteVO> getNote(NoteDirDTO noteDirDTO) {
        List<Note> noteVOS = noteMapper.getNoteVOS(noteDirDTO);
        return noteVOS.stream().map(note -> {
            NoteVO noteVO = new NoteVO();
            BeanUtils.copyProperties(note, noteVO);
            noteVO.setDirChildNodes(JSONArray.parseArray(note.getDirChildNodes()));
            return noteVO;
        }).toList();
    }


    @Override
    public NoteContentVO getNoteContent(Long id) {
        LambdaQueryWrapper<Note> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Note::getId, id)
                .select(Note::getSummary, Note::getNoteDirectory, Note::getNoteContent);
        Note note = noteMapper.selectOne(queryWrapper);
        NoteContentVO noteContentVO = new NoteContentVO();
        BeanUtils.copyProperties(note, noteContentVO);
        noteContentVO.setNoteDirectory(JSONArray.parseArray(note.getNoteDirectory()));
        return noteContentVO;
    }

    @Override
    public Boolean updateNoteChildNodes(NoteDirDTO noteDirDTO) {
        LambdaUpdateWrapper<Note> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Note::getDirChildNodes, noteDirDTO.getDirChildNodes().toJSONString())
                .eq(Note::getId, noteDirDTO.getDirPrevNodeId());
        noteMapper.update(updateWrapper);
        return true;
    }

    @Override
    public Note getNote(Long noteId) {
        // 获取笔记信息
        LambdaQueryWrapper<Note> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Note::getId, noteId)
                .select(Note::getUserId, Note::getNoteDirectory, Note::getNoteContent,
                        Note::getPrevNodeId, Note::getPrevNodeType);
        return noteMapper.selectOne(queryWrapper);
    }
}
